package com.basic.tools.codegen.entity.domain;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.basic.tools.codegen.config.properties.GenProperties;
import com.basic.tools.codegen.entity.GenTable;
import com.basic.tools.codegen.entity.GenTableColumn;
import com.basic.tools.codegen.entity.TemplateConfig;
import com.basic.tools.codegen.gen.ColumnDefinition;
import com.basic.tools.codegen.gen.JavaColumnDefinition;
import com.basic.tools.codegen.gen.TableDefinition;
import com.basic.tools.codegen.service.TemplateConfigService;
import com.basic.tools.codegen.util.FieldUtil;
import com.basic.tools.template.entity.TemplateBridge;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Component
@ComponentScan(basePackages = {"cn.hutool.extra.spring"})
@Import(cn.hutool.extra.spring.SpringUtil.class)
public class GenUtils {


    public static Map<String, String> templateMap;


    static {
        templateMap = new HashMap<String, String>() {
            {
                put("Controller", "vms/Controller.java.vm");
                put("Entity", "vms/entity.java.vm");
            }
        };
    }

    public static String getOutURL(GenTable genTable, String subfix) {
        String pathPackage = genTable.getPackageName();
        if (org.apache.commons.lang.StringUtils.isBlank(pathPackage)) {
            pathPackage = "main.java";
        }
        if (StringUtils.isNotBlank(pathPackage)) {
            pathPackage = pathPackage.replaceAll("\\.", "/");
        }
        String className = genTable.getClassName();
        return pathPackage + "/" + className + subfix + ".java";
    }


    public static String getTablePrefix(String tableName) {
        //TODO
//        if (tableName.indexOf("_") != -1) {
//            return tableName.substring(0, tableName.indexOf("_"));
//        }
        return "";
    }

    public static GenTable tableD2tableG(TableDefinition tableDefinition, String datasourceId) {
        GenProperties genProperties = (GenProperties) SpringUtil.getBean("genProperties");
        GenTable genTable = new GenTable();
        String tableName = tableDefinition.getTableName();
        genTable.setDatasourceId(datasourceId);
        genTable.setTableName(tableName);
        genTable.setTableComment(tableDefinition.getComment());
        if (StringUtils.isBlank(tableDefinition.getComment())) {
            genTable.setTableComment(FieldUtil.underlineFilter(tableName));
        }
        genTable.setClassName(FieldUtil.underlineFilter(tableName));
        genTable.setFunctionAuthor(genProperties.getFunctionAuthor());
        genTable.setPackageName(genProperties.getPackageName());
        genTable.setModuleName(genProperties.getModuleName());
        genTable.setGid(genProperties.getGid());
        genTable.setBusinessName(FieldUtil.underlineFilter(tableName));
        genTable.setFunctionName(FieldUtil.underlineFilter(tableName));
        genTable.setTablePrefix(getTablePrefix(tableName));

        List<GenTableColumn> clist = new ArrayList<>();
        List<ColumnDefinition> columnDefinitions = tableDefinition.getColumnDefinitions();
        for (ColumnDefinition cd : columnDefinitions) {
            clist.add(tableDC2tableGC(cd));
        }
        genTable.setColumns(clist);


        return genTable;
    }

    public static GenTableColumn tableDC2tableGC(ColumnDefinition columnDefinition) {
        JavaColumnDefinition javaColumnDefinition = (JavaColumnDefinition) columnDefinition;
        GenTableColumn genTableColumn = new GenTableColumn();

//        javaColumnDefinition.getMybatisJdbcType();
//        javaColumnDefinition.getJavaFieldNameUF();

        genTableColumn.setColumnComment(javaColumnDefinition.getComment());
        genTableColumn.setColumnName(javaColumnDefinition.getColumnName());
        genTableColumn.setColumnType(javaColumnDefinition.getType());
        genTableColumn.setIsPk(javaColumnDefinition.getIsPk() == true ? "1" : "0");
        genTableColumn.setJavaField(javaColumnDefinition.getJavaFieldName());
        genTableColumn.setJavaType(javaColumnDefinition.getFieldTypeBox());

        List<String> strings = Arrays.asList("id", "update_by", "create_by", "create_date", "update_date");
        boolean b = strings.contains(genTableColumn.getColumnName().toLowerCase());
        if (strings.get(0).equals(genTableColumn.getColumnName().toLowerCase())) {
            genTableColumn.setIsList("1");
            genTableColumn.setIsQuery("1");
        }
        if (!b) {
            genTableColumn.setIsEdit("1");
            genTableColumn.setIsInsert("1");
            genTableColumn.setIsList("1");
            genTableColumn.setIsQuery("1");
        }
        genTableColumn.setHtmlType("input");
        return genTableColumn;
    }

    public static String generate(VelocityContext context, String template) {
        StringReader reader = new StringReader(template);
        StringWriter writer = new StringWriter();
        // 不用vm文件
        Velocity.evaluate(context, writer, "mystring", reader);
        try {
            writer.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return writer.toString();
    }

    public static List<TemplateBridge> getTemplateBridges(GenTable genTable) {
        List<TemplateBridge> listt = new ArrayList<>();
        Set<Map.Entry<String, String>> entries = templateMap.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            Map<String, Object> data = new HashMap<>();
            String ClassName = FieldUtil.upperFirstLetter(getClassName(genTable.getClassName(), genTable.getTablePrefix()));
            data.put("ClassName", ClassName);
            data.put("className", FieldUtil.lowerFirstLetter(ClassName));
            data.put("packageName", genTable.getPackageName());//main.java.com
            data.put("muduleName", genTable.getModuleName());
            ;//basic
            data.put("author", genTable.getFunctionAuthor());//coder
            data.put("functionName", genTable.getFunctionName());//sysDictType
            data.put("busName", genTable.getBusinessName());//sysDictType
            data.put("tableName", genTable.getTableName());//sys_dict_type
            data.put("tableComment", genTable.getTableComment());//表描述
            data.put("tablePrefix", genTable.getTablePrefix());//表前缀
            data.put("dateNow", DateUtil.now());
            data.put("gt", genTable);
            data.put("columns", genTable.getColumns());
            String outURL = getOutURL(genTable, key);
            TemplateBridge templateBridge = new TemplateBridge(data, value, outURL, key);
            listt.add(templateBridge);
        }
        return listt;
    }

    public static Map<String, String> generTableByOnline(List<TemplateConfig> templateConfigs, GenTable genTable, ZipOutputStream zip, TemplateConfigService templateConfigService) throws IOException {
        VelocityContext data = new VelocityContext();//sysDictType
        String ClassName = FieldUtil.upperFirstLetter(getClassName(genTable.getClassName(), genTable.getTablePrefix()));
        data.put("ClassName", ClassName);
        data.put("className", FieldUtil.lowerFirstLetter(ClassName));
        data.put("packageName", genTable.getPackageName());//main.java.com
        data.put("muduleName", genTable.getModuleName());
        ;//basic
        data.put("author", genTable.getFunctionAuthor());//coder
        data.put("functionName", genTable.getFunctionName());//sysDictType
        data.put("busName", genTable.getBusinessName());//sysDictType
        data.put("tableName", genTable.getTableName());//sys_dict_type
        data.put("tableComment", genTable.getTableComment());//表描述
        data.put("tablePrefix", genTable.getTablePrefix());//表前缀
        data.put("dateNow", DateUtil.now());
        data.put("gt", genTable);
        data.put("columns", genTable.getColumns());
        Map<String, String> remap = new HashMap();
        for (TemplateConfig templateConfig : templateConfigs) {
            if (templateConfig.getIsDeleted() == 1) {
                continue;
            }
            String template = templateConfig.getContent();
            String rtemplates = "";
            String rids = templateConfig.getRids();
            if (StringUtils.isNotBlank(rids)) {
                for (String rid : rids.split(",")) {
                    try {
                        if (StringUtils.isNumeric(rid)) {
                            TemplateConfig byId = templateConfigService.getById(Integer.parseInt(rid));
                            if (byId != null) {
                                rtemplates += byId.getContent();
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            String recode = GenUtils.generate(data, rtemplates + template);
            String fileName = GenUtils.generate(data, templateConfig.getFileName()).replaceAll("\\.", "/");
            remap.put(templateConfig.getName(), recode);
            zip.putNextEntry(new ZipEntry(replaceLastStr(fileName, "/", ".")));
            IOUtils.write(recode, zip, "UTF-8");
        }
        return remap;
    }

    public static String getClassName(String className, String prefix) {
        String re = className;
        if (!StringUtils.isBlank(prefix)) {
            re = className.substring(prefix.length());
        }
        return re;
    }

    public static String replaceLastStr(String data, String from, String to) {
        String re = data;
        int i = data.lastIndexOf(from);
        if (i != -1) {
            re = data.substring(0, i) + to + data.substring(i + from.length());
        } else {
            re = data + ".java";
        }
        return re;
    }

    public static void main(String[] args) {
        String asd = "asd4/asd3/asd2/asd1";
//        int i = asd.lastIndexOf("/");
//        String s = asd.substring(0, i) + "." + asd.substring(i+1);
//        System.out.println(s);
        System.out.println(replaceLastStr(asd, "/", "."));

    }


}
